package com.czy.owner.net.subscribers;

import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.widget.Toast;

import com.czy.owner.application.CzyApplication;
import com.czy.owner.db.UserHelper;
import com.czy.owner.global.Constants;
import com.czy.owner.net.api.BaseApi;
import com.czy.owner.net.exception.HttpTimeException;
import com.czy.owner.net.http.cookie.CookieResulte;
import com.czy.owner.net.listener.HttpOnNextListener;
import com.czy.owner.net.utils.AppUtil;
import com.czy.owner.net.utils.CookieDbUtil;
import com.czy.owner.net.utils.JsonUtil;
import com.czy.owner.net.utils.MyLoadView;
import com.czy.owner.ui.login.LoginActivity;
import com.czy.owner.utils.ActivityHelper;
import com.czy.owner.utils.MyLog;
import com.czy.owner.utils.PhoneUtils;
import com.czy.owner.utils.SharedPreferencesUtils;
import com.czy.owner.utils.tiputils.MProgressDialog;
import com.trello.rxlifecycle.components.support.RxAppCompatActivity;
import java.lang.ref.SoftReference;
import java.net.ConnectException;
import java.net.SocketTimeoutException;

import rx.Observable;
import rx.Subscriber;

/**
 * 用于在Http请求开始时，自动显示一个ProgressDialog
 * 在Http请求结束是，关闭ProgressDialog
 * 调用者自己对请求数据进行处理
 * Created by wangyang on 2017/4/26.
 */
public class ProgressSubscriber<T> extends Subscriber<T> {
    /*是否弹框*/
    private boolean showPorgress = true;
    /* 软引用回调接口*/
    private  HttpOnNextListener  mSubscriberOnNextListener;
    /*软引用反正内存泄露*/
    private SoftReference<RxAppCompatActivity> mActivity;
    /*加载框可自己定义*/
    private MProgressDialog pd;
    /*请求数据*/
    private BaseApi api;
     /*取消订阅*/
     private boolean isCancleSubscriber ;

    /**
     * 构造
     *
     * @param api
     */
    public ProgressSubscriber(BaseApi api) {
        this.api = api;
        this.mSubscriberOnNextListener = api.getListener();
        this.mActivity = new SoftReference<>(api.getRxAppCompatActivity());
        setShowPorgress(api.isShowProgress());
        if (api.isShowProgress()) {
            initProgressDialog(api.isCancel(),api.getProgressTitle());
        }
    }


    /**
     * 初始化加载框
     */
    private void initProgressDialog(boolean cancel,String progressTitle) {
        Context context = mActivity.get();
        if (pd == null && context != null) {
            pd = new MProgressDialog(context);
        }
    }


    /**
     * 显示加载框
     */
    private void showProgressDialog() {
        if (!isShowPorgress()) return;
        Context context = mActivity.get();
        if (pd == null || context == null) return;

            pd.ShowLoadView();

    }


    /**
     * 隐藏
     */
    private void dismissProgressDialog() {
        if (!isShowPorgress()) return;

            pd.CancleLoadView();

//        加载框消失 取消对observable的订阅，同时也取消了http请求
        if (mSubscriberOnNextListener!= null) {
            mSubscriberOnNextListener.onCancel();
        }
        onCancelProgress();


    }


    /**
     * 订阅开始时调用
     * 显示ProgressDialog
     */
    @Override
    public void onStart() {
        showProgressDialog();
        /*缓存并且有网*/
        try {
            if (api.isCache() && AppUtil.isNetworkAvailable(CzyApplication.getInstance().getAppContext())) {
             /*获取缓存数据*/
                CookieResulte cookieResulte = CookieDbUtil.getInstance().queryCookieBy(api.getUrl());
                if (cookieResulte != null) {

                    long time = (System.currentTimeMillis() - cookieResulte.getTime()) / 1000;
                    if (time < api.getCookieNetWorkTime()) {
                        if (mSubscriberOnNextListener!= null) {
                            mSubscriberOnNextListener.onCacheNext(cookieResulte.getResulte());
                        }
                        onCompleted();
                        unsubscribe();
                    }
                }
            }
        }catch (Exception e){

        }

    }

    /**
     * 完成，隐藏ProgressDialog
     */
    @Override
    public void onCompleted() {
        dismissProgressDialog();
    }

    /**
     * 对错误进行统一处理
     * 隐藏ProgressDialog
     *
     * @param e
     */
    @Override
    public void onError(Throwable e) {
        dismissProgressDialog();
        // TODO modified by King 2017/07/10:网络状态码
        if(e instanceof HttpTimeException && ((HttpTimeException)e).isCodeError()){
                Toast.makeText(api.getRxAppCompatActivity(), "" + ((HttpTimeException) e).getExp(), Toast.LENGTH_SHORT).show();
        }else  if (api.isCache()) { /*需要緩存并且本地有缓存才返回*/

            Observable.just(api.getUrl()).subscribe(new Subscriber<String>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
//                    errorDo(e);
                }

                @Override
                public void onNext(String s) {
                    /*获取缓存数据*/
                    CookieResulte cookieResulte = CookieDbUtil.getInstance().queryCookieBy(s);
                    if (cookieResulte == null) {
                        throw new HttpTimeException("网络错误");
                    } else {
                        boolean flag = JsonUtil.getJsonValuesBoolean(cookieResulte.getResulte(), "flag");
                        String exp = JsonUtil.getJsonValuesString(cookieResulte.getResulte(), "exp");
                        int errorCode = JsonUtil.getJsonValuesInt(cookieResulte.getResulte(), "errorCode");
                        if (!flag) {
                            // TODO 检查错误码,如是110 登录超时
                            switch (errorCode) {
                                case 110:
                                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_AUTH_KEY_STORAGE);
                                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_SESSION_INFO_MODEL);
                                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_USER_INFO_MODEL);
                                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_OWNER_INFO_MODEL);
                                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_CHAIN_STORES_MODEL);
                                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_BINDSTOREID);
                                    SharedPreferencesUtils.remove(Constants.SHARED_PREFERENCES_KEY_IS_STORE_BIND);
                                    ActivityHelper.getInstance().finishAllActivity();
                                    UserHelper.getInstance().setUserInfoModel(api.getRxAppCompatActivity(),null);
                                    UserHelper.getInstance().setSessionInfoModel(api.getRxAppCompatActivity(),null);
                                    UserHelper.getInstance().setOwnerInfoModel(api.getRxAppCompatActivity(),null);
                                    UserHelper.getInstance().setmChainStoresList(api.getRxAppCompatActivity(),null);
                                    SharedPreferencesUtils.setParam(api.getRxAppCompatActivity(), Constants.SHARED_PREFERENCES_KEY_IS_STORE_BIND_DIALOG, 0);
                                    UserHelper.getInstance().setIsLogined(false);
                                    Intent intent = new Intent(api.getRxAppCompatActivity(), LoginActivity.class);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    api.getRxAppCompatActivity().startActivity(intent);
                                    break;
                                default:
                                    PhoneUtils.ShowToastMessage(api.getRxAppCompatActivity(), exp);
                                    //特殊处理以后修改
                                    if(exp.contains("套餐已不存在或者过期")){
                                        api.getRxAppCompatActivity().finish();
                                    }

                            }
                            throw new HttpTimeException(exp);
                        }



                    }

                    long time = (System.currentTimeMillis() - cookieResulte.getTime()) / 1000;
                    if (time < api.getCookieNoNetWorkTime()) {
                        if (mSubscriberOnNextListener!= null) {
                            mSubscriberOnNextListener.onCacheNext(cookieResulte.getResulte());
                        }
                    } else {
                        CookieDbUtil.getInstance().deleteCookie(cookieResulte);
                        throw new HttpTimeException("网络错误");
                    }
                }
            });
        } else {
           MyLog.e("yang","请求异常==="+e.getMessage());
            if(!TextUtils.isEmpty(e.getMessage())){
                if(e.getMessage().contains("请重新登录")){
                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_AUTH_KEY_STORAGE);
                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_SESSION_INFO_MODEL);
                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_USER_INFO_MODEL);
                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_OWNER_INFO_MODEL);
                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_CHAIN_STORES_MODEL);
                    SharedPreferencesUtils.remove(UserHelper.getInstance().getUserAccount() + Constants.SHARED_PREFERENCES_KEY_BINDSTOREID);
                    SharedPreferencesUtils.remove(Constants.SHARED_PREFERENCES_KEY_IS_STORE_BIND);
                    ActivityHelper.getInstance().finishAllActivity();
                    UserHelper.getInstance().setUserInfoModel(api.getRxAppCompatActivity(),null);
                    UserHelper.getInstance().setSessionInfoModel(api.getRxAppCompatActivity(),null);
                    UserHelper.getInstance().setOwnerInfoModel(api.getRxAppCompatActivity(),null);
                    UserHelper.getInstance().setmChainStoresList(api.getRxAppCompatActivity(),null);
                    SharedPreferencesUtils.setParam(api.getRxAppCompatActivity(), Constants.SHARED_PREFERENCES_KEY_IS_STORE_BIND_DIALOG, 0);
                    UserHelper.getInstance().setIsLogined(false);
                    Intent intent = new Intent(api.getRxAppCompatActivity(), LoginActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    api.getRxAppCompatActivity().startActivity(intent);
                }
            }

            errorDo(e);
        }
    }

    /*错误统一处理*/
    private void errorDo(Throwable e) {
        Context context = mActivity.get();
        if (context == null) return;
        if (e instanceof SocketTimeoutException) {
            PhoneUtils.ShowToastMessage(context,"网络超时");
        } else if (e instanceof ConnectException) {
            PhoneUtils.ShowToastMessage(context,"网络错误");
        }
//        if (mSubscriberOnNextListener!= null) {
//            mSubscriberOnNextListener.onError(e);
//        }
    }

    /**
     * 将onNext方法中的返回结果交给Activity或Fragment自己处理
     *
     * @param t 创建Subscriber时的泛型类型
     */
    @Override
    public void onNext(T t) {
        if (mSubscriberOnNextListener!= null) {
            mSubscriberOnNextListener.onNext(t);
        } else {
            Context context = mActivity.get();
            PhoneUtils.ShowToastMessage(context,"请求错误,请重试");

        }
    }

    /**
     * 取消ProgressDialog的时候，取消对observable的订阅，同时也取消了http请求
     */
    public void onCancelProgress() {
        if (!this.isUnsubscribed()) {
            this.unsubscribe();
        }
    }


    public boolean isShowPorgress() {
        return showPorgress;
    }

    /**
     * 是否需要弹框设置
     *
     * @param showPorgress
     */
    public void setShowPorgress(boolean showPorgress) {
        this.showPorgress = showPorgress;
    }
}